package xman.mstruts.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;

import javax.annotation.Resource;

import xman.mstruts.dao.GenericDAO;
import xman.mstruts.entity.Id;

//@Service
@SuppressWarnings({ "rawtypes", "unchecked" })
public class GenericService<T extends Id> {
    @Resource
    protected GenericDAO genericDAO;
    
    private WeakHashMap<String, Object> cache = new WeakHashMap<String, Object>();
    
    public Object get(Class<T> clazz, Map params, String sqlId) {
        return genericDAO.get(clazz, params, sqlId);
    }
    
    public List list(Class<T> clazz, Map params, String sqlId) {
        return genericDAO.list(clazz, params, sqlId);
    }
    
    public T getEntity(Class<T> clazz, Map params) {
        T entity = (T) genericDAO.getEntity(clazz, params);
        if (entity != null && entity.getId() > 0) {
            addCache(clazz, entity.getId(), entity);
        }
        return entity;
    }
    
    public List<T> listEntity(Class<T> clazz, Map params) {
        return (List<T>) genericDAO.listEntity(clazz, params);
    }
    
    public Integer listRecord(Class<T> clazz, Map params) {
        return (Integer) genericDAO.listRecord(clazz, params);
    }
    
    public Integer insertReturnId(Class<T> clazz, T entity) {
        Integer id = (Integer) genericDAO.insertReturnId(clazz, entity);
        if (id != null && id > 0) {
            entity.setId(id);
        }
        return id;
    }
    
    public Integer updateEntity(Class<T> clazz, T entity) {
        Integer count = genericDAO.updateEntity(clazz, entity);
        if (count != null && count > 0) {
            delCache(clazz, entity.getId());
        }
        return count;
    }
    
    public Integer deleteEntity(Class<T> clazz, T entity) {
        Integer count = genericDAO.deleteEntity(clazz, entity);
        if (count != null && count > 0) {
            delCache(clazz, entity.getId());
        }
        return count;
    }
    
    protected String sql(Class<T> clazz) {
        String sqlId = new Throwable().getStackTrace()[1].getMethodName();
        return clazz.getSimpleName() + "DAO." + sqlId;
    }
    
    public T getEntityById(Class<T> clazz, int id) {
        T entity = (T) cache.get(key(clazz, id));
        if (entity != null)
            return entity;
        Map params = new HashMap();
        params.put("id", id);
        return this.getEntityById(clazz, id);
    }
    
    private void addCache(Class<T> clazz, int id, T obj) {
        cache.put(key(clazz, id), obj);
    }
    
    private void delCache(Class<T> clazz, int id) {
        cache.remove(key(clazz, id));
    }
    
    private String key(Class<T> clazz, int id) {
        return clazz.getSimpleName() + id;
    }
}
